package com.chuangjian.hire.media.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.kisso.annotation.Login;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chuangjian.hire.common.controller.BaseController;
import com.chuangjian.hire.common.dto.FilterDTO;
import com.chuangjian.hire.common.dto.R;
import com.chuangjian.hire.media.dao.MediaExportMapper;
import com.chuangjian.hire.media.dao.MediaItemMapper;
import com.chuangjian.hire.media.domain.MediaExportDO;
import com.chuangjian.hire.media.domain.MediaItemDO;
import com.chuangjian.hire.media.dto.MediaFilterDTO;
import com.chuangjian.hire.media.dto.MediaItemDTO;
import com.chuangjian.hire.media.dto.TypesDTO;
import com.chuangjian.hire.media.service.S3Service;
import com.chuangjian.hire.users.dao.UsersMapper;
import com.chuangjian.hire.users.dto.UserDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Slf4j
@Api(tags = "下载中心")
@RestController
@RequestMapping("/mediaExport")
public class MediaExportController extends BaseController {

    @Resource
    private MediaExportMapper mediaExportMapper;


    @Resource
    private MediaItemMapper mediaItemMapper;

    @Resource
    private MediaItemController mediaItemController;

    @Resource
    private UsersMapper usersMapper;

    ExecutorService executorService = Executors.newFixedThreadPool(5);


    @Login
    @PostMapping("export")
    @ApiOperation("导出Excel")
    public R export(@RequestBody MediaFilterDTO media) throws IOException {


        String fileName = "导出数据" + DateUtil.format(LocalDateTime.now(), "yyyy_MM_dd_HH_mm_ss") + ".xls";
        String key = "export/" + fileName;

        UserDTO userInfo = getUserInfo();
        String roleNames = usersMapper.getRoleNameList(userInfo.getId()).stream().collect(Collectors.joining(","));

        MediaExportDO exp = new MediaExportDO();
        exp.setUrl(key);
        exp.setName(fileName);
        exp.setRoleName(roleNames);
        exp.setCreator(userInfo.getName());
        exp.setCreatorId(userInfo.getId());
        exp.setCreateDate(new Date());
        mediaExportMapper.insert(exp);

        executorService.execute(() -> {
            try {

                FileOutputStream fileOutputStream = new FileOutputStream(fileName);
                ExcelWriter writer = HutoolExportExcelUtil.export(MediaItemDO.class, "导出数据");

                int current = 1;
                int pageSize = 500;
                List<MediaItemDTO> records;
                do {
                    Page page = new Page<>(current, pageSize);
                    Page<MediaItemDTO> pageR = mediaItemController.pageList2(page, media);
                    records = pageR.getRecords();
                    writer.write(records, true);
                    current++;
                } while (records.size() == pageSize);

                writer.flush(fileOutputStream, true);
                writer.close();
                IoUtil.close(fileOutputStream);

                S3Service.upload(key, new File(fileName));

                exp.setStatus(1);
                mediaExportMapper.updateById(exp);

                FileUtil.del(fileName);

            } catch (Exception e) {
                log.error("导出失败", e);
            }
        });


        return R.success(true);
    }

    @Login
    @PostMapping("pageList")
    @ApiOperation("获取导出列表")
    public R<MediaExportDO> pageList(Page page, @RequestBody FilterDTO param) {

        Page pageResult = mediaExportMapper.selectPage(page,
                Wrappers.lambdaQuery(MediaExportDO.class)
                        .like(StringUtils.isNotBlank(param.getCreator()), MediaExportDO::getCreator, param.getCreator())
                        .ge(param.getStartDate() != null, MediaExportDO::getCreateDate, param.getStartDate())
                        .lt(param.getEndDate() != null, MediaExportDO::getCreateDate, param.getEndDate())
                        .orderByDesc(MediaExportDO::getId)
        );
        List<MediaExportDO> records = pageResult.getRecords();
        List<MediaExportDO> collect = records.stream().map(it -> {
            it.setUrl(MediaItemController.baseUrl + it.getUrl());
            return it;
        }).collect(Collectors.toList());
        pageResult.setRecords(collect);
        return R.success(pageResult);
    }


    @Login
    @PostMapping("download")
    @ApiOperation("导出")
    public R<MediaExportDO> download(@RequestBody MediaExportDO param) {


        MediaExportDO export = new MediaExportDO();
        export.setId(param.getId());

        export.setStatus(2);

        mediaExportMapper.updateById(export);

        return R.success(export);
    }


    @PostMapping("typePageList")
    @ApiOperation("获取类型列表")
    public R<TypesDTO> typePageList(Page page, @RequestBody TypesDTO param) {

        List<TypesDTO> mediaItemDOS = mediaItemMapper.typePageList(page,
                param.getSubType()
        );
        page.setRecords(mediaItemDOS);

        return R.success(page);
    }

    @PostMapping("typeChange")
    @ApiOperation("获取类型列表")
    public R<TypesDTO> typeChange(@RequestBody TypesDTO param) {

        MediaItemDO item = new MediaItemDO();
        item.setGenres(param.getGenresNew());

        List<MediaItemDO> mediaItemDOS = mediaItemMapper.selectList(
                Wrappers.lambdaQuery(MediaItemDO.class)
                        .eq(MediaItemDO::getSubType, param.getSubType())
                        .eq(MediaItemDO::getGenres, param.getGenres())
                        .orderByDesc(MediaItemDO::getId)
        );

        if (CollectionUtil.isNotEmpty(mediaItemDOS)) {

            mediaItemDOS.forEach(it -> {
                it.setGenres(param.getGenresNew());
                mediaItemMapper.updateById(it);
            });
        }
        return R.success(true);
    }

}

